using System;

namespace ServiceModel.Syndication.LEAP2A {
    /// <summary>
    /// Represents a pair of links in LEAP2A
    /// </summary>
    public class LeapLinkPair {
        /// <summary>
        /// The relationship in the "Has" direction
        /// </summary>
        public readonly LeapPredicates Value;

        /// <summary>
        /// The inverse of the relationship
        /// </summary>
        public readonly LeapPredicates Inverse;

        public readonly string CustomValue;

        public readonly string CustomInverse;

        /// <summary>
        /// Initializes a new instance of the <see cref="LeapLinkPair"/> class, 
        /// with a pair of relationships.
        /// </summary>
        /// <param name="link">The relationship in the "Has" direction</param>
        /// <param name="inverseLink">The inverse of the relationship (Is---Of)</param>
        public LeapLinkPair(LeapPredicates link, LeapPredicates inverseLink) {
            this.Value = link;
            this.Inverse = inverseLink;
        }

        public LeapLinkPair(string link, string inverseLink) {
            this.Value = LeapPredicates.Custom;
            this.Inverse = LeapPredicates.Custom;
            this.CustomValue = link;
            this.CustomInverse = inverseLink;
        }

        /// <summary>
        /// HasPart/PartOf link
        /// </summary>
        public static readonly LeapLinkPair Part = new LeapLinkPair(LeapPredicates.HasPart, LeapPredicates.IsPartOf);

        /// <summary>
        /// HasEvidence/IsEvidenceOf link
        /// </summary>
        public static readonly LeapLinkPair Evidence = new LeapLinkPair(LeapPredicates.HasEvidence, LeapPredicates.IsEvidenceOf);
        
        /// <summary>
        /// SupportedBy/Supports link
        /// </summary>
        public static readonly LeapLinkPair Support = new LeapLinkPair(LeapPredicates.SupportedBy, LeapPredicates.Supports);
        
        /// <summary>
        /// Atom related link, this is the same as the LEAP2 relation link.  
        /// It should be used in the link element of an Atom entry
        /// </summary>
        public static readonly LeapLinkPair Related = new LeapLinkPair(LeapPredicates.AtomRelated, LeapPredicates.AtomRelatedBy);
        
        /// <summary>
        /// LEAP2A relation link, this is the same as the Atom related link.
        /// It should be used for relationships which are not a link within an Atom entry
        /// </summary>
        public static readonly LeapLinkPair Relation = new LeapLinkPair(LeapPredicates.LeapRelation, LeapPredicates.LeapRelationOf);
        
        /// <summary>
        /// HasOutcome/IsOutcomeOf link
        /// </summary>
        public static readonly LeapLinkPair Outcome = new LeapLinkPair(LeapPredicates.HasOutcome, LeapPredicates.IsOutcomeOf);
        
        /// <summary>
        /// AttendedBy/Attended link
        /// </summary>
        public static readonly LeapLinkPair Attendee = new LeapLinkPair(LeapPredicates.AttendedBy, LeapPredicates.Attends);

        /// <summary>
        /// ReflectsOn/ReflectedOnBy link
        /// </summary>
        public static readonly LeapLinkPair Reflection = new LeapLinkPair(LeapPredicates.ReflectedOnBy, LeapPredicates.ReflectsOn);

        /// <summary>
        /// HasAgenda/IsAgendaOf link
        /// </summary>
        public static readonly LeapLinkPair Agenda = new LeapLinkPair(LeapPredicates.HasAgenda, LeapPredicates.IsAgendaOf);

        public LeapLinkPair Invert() {
            if (Value == LeapPredicates.Custom){
                return new LeapLinkPair(CustomInverse, CustomValue);
            }

            return new LeapLinkPair(Inverse, Value);
        }
    }
}
